<?php
class system_concept_rowset implements ArrayAccess, SeekableIterator, Countable {
	protected $_data = array();
	protected $_rows = array();
	protected $_rowClass = 'system_concept_row';
	//protected $_count = 0;
	protected $_position = 0;
	
	/**
	 * @varsystem_concept_abstract
	 */
	protected $_concept = null;
	
	public function __construct(array $data, system_concept_abstract $concept, $rowClass = null) {
		$this->_data = $data;
		$this->_concept = clone $concept;
		unset($concept);
		//$this->_count = count($data);
		$rowClass!=null&&$this->setRowClass($rowClass);
	}
	public function toArray() {
		return $this->_data;
	}
	
	public function setRowClass($rowClass) {
		$this->_rowClass = $rowClass;
		return $this;
	}
	public function getRowClass() {
		return $this->_rowClass;
	}
	
	//SeekableIterator 接口方法
	public function seek($position) {
		$position = intval($position);
		if($position<0||$position>=$this->count()) {
			throw new system_exception("llegal index $position");
		}
		$this->_position = $position;
	}
	
	/**
	 * @return system_concept_row
	 */
	public function current() {
		if(!$this->valid()) {
			return null;
		}
		if(!isset($this->_rows[$this->_position])||empty($this->_rows[$this->_position])) {
			$this->_rows[$this->_position] = new $this->_rowClass($this->_data[$this->_position], $this->_concept);
		}
		return $this->_rows[$this->_position];
	}
	public function key() {
		return $this->_position;
	}
	
	public function next() {
		++$this->_position;
	}
	
	public function rewind() {
		$tmp = array();
		foreach($this->_data as $v) {
			$tmp[] = $v;
		}
		$this->_data = $tmp;
		
		//$this->_rows = array();
		$tmp = array();
		foreach($this->_rows as $v) {
			$tmp[] = $v;
		}
		$this->_rows = $tmp;
		$this->_position = 0;
	
	}
	public function valid() {
		return isset($this->_data[$this->_position]);
	
		//return $this->_position >= 0 && $this->_position < $this->count();
	}
	
	//Contable 接口方法
	public function count() {
		return count($this->_data);
	}
	
	//ArrayAccess 接口方法
	public function offsetExists($offset) {
		return isset($this->_data[$offset]);
	}
	
	/**
	 * 
	 * @param unknown_type $offset
	 * @return system_concept_row
	 */
	public function offsetGet($offset) {
		if(isset($this->_data[$offset])) {
			if(!isset($this->_rows[$offset])) {
				$this->_rows[$offset] = new $this->_rowClass($this->_data[$offset], $this->_concept);
			}
			return $this->_rows[$offset];
		} else {
			throw new system_exception("Illegal index $offset");
		}
	}
	public function offsetSet($offset, $value) {
		if($value instanceof system_concept_row) {
			$value = $value->toArray();
		}
		if(is_null($offset)) {
			$this->_data[] = $value;
		} else {
			$this->_data[$offset] = $value;
		}
	}
	public function offsetUnset($offset) {
		if(isset($this->_data[$offset])) {
			unset($this->_data[$offset]);
		}
		if(isset($this->_rows[$offset])) {
			unset($this->_rows[$offset]);
		}
	}
	
	/**
	 * @return system_concept_row
	 */
	public function create($data = array()) {
		if(count($this->_rows)!==count($this->_data)) {
			foreach($this->_data as $k => $v) {
				if(!isset($this->_rows[$k])) {
					$this->_rows[$k] = new $this->_rowClass($v, $this->_concept);
				}
			}
		}
		//$row = $this->_concept->create($data);
		$rowClass = $this->getRowClass();
		$row = new $rowClass($this->_concept->getRowCols($data), $this->_concept);
		$this->_data[] = $row->toArray();
		
		$key = count($this->_data)-1;
		return $this->_rows[$key] = $row;
	
	}
}